﻿using Gobang.DataServer.DbOperation;
using Gobang.Server.Area;
using Gobang.Server.Servers.ServerTask;
using Gobang.ToolClass;
using Gobang.ToolClass.Model;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net;

namespace Gobang.Server.Servers
{
    internal class ServersCenter : ServersBase, IDisposable
    {
        internal readonly UserInfoServer _userServer;
        private readonly ConcurrentQueue<ReceiveData> _receiveDatas;
        private readonly Thread _thread;
        public ConcurrentQueue<ReceiveData> ReceiveDatas => _receiveDatas;
        internal readonly AreaCenter _areaCenter;
        public ServersCenter()
        {
            Client.DataArrival = DataArrival;
            _userServer = new UserInfoServer();
            _receiveDatas = new ConcurrentQueue<ReceiveData>();
            _thread = new Thread(Execute);
            _thread.Start();
            _areaCenter = new AreaCenter();
        }
        private void DataArrival(byte[] data, IPEndPoint iPEndPoint)
        {
            _receiveDatas.Enqueue(new ReceiveData
            {
                Data = data,
                IPPoint = iPEndPoint
            });

        }
        private volatile bool _close = false;
        public void Dispose()
        {
            _close = true;
            Client.Active = false;
            try
            {
                if (_thread != null)
                {
                    _thread.Interrupt();
                    _thread.Join();
                }
            }
            catch (Exception ex)
            {
#if DEBUG
                Trace.WriteLine(ex.Message);
#endif
            }
        }

        private void Execute()
        {
            while (!_close)
            {
                if (!_receiveDatas.TryDequeue(out var result))
                {
                    Thread.Sleep(1);
                    continue;
                }
                try
                {
                    var mes = System.Text.Encoding.UTF8.GetString(result.Data);
                    MsgMergeModel msgMergeModel = mes.DeserializeObject<MsgMergeModel>();
                    switch (msgMergeModel.SendMsgType)
                    {
                        case MsgType.Msg:
                            Task.Factory.StartNew(() =>
                            {
                                MsgTypeMsgTask task = new MsgTypeMsgTask(this);
                                task.MsgTypeMsg(msgMergeModel, result.IPPoint);
                            });
                            break;
                        case MsgType.None:
                            Task.Factory.StartNew(() =>
                            {
                                MsgTypeNoneTask task = new MsgTypeNoneTask(this);
                                task.MsgTypeNone(msgMergeModel, result.IPPoint);
                            });

                            break;
                        case MsgType.Command:
                            Task.Factory.StartNew(() =>
                            {
                                MsgTypeCommandTask task = new MsgTypeCommandTask(this);
                                task.MsgTypeCommand(msgMergeModel, result.IPPoint);
                            });

                            break;
                    }
                }
                catch (Exception ex)
                {
#if DEBUG
                    Trace.WriteLine(ex.Message);
#endif
                }
            }
        }
    }
    public class ReceiveData
    {
        public byte[] Data { get; set; }
        public IPEndPoint IPPoint { get; set; }
    }
}
